`timescale 1ns/100ps

`include "sim_glb.sv"

module tc;

localparam          CW_NUM                  = 1000;
localparam          CLK_PRD                 = 5;

localparam          PZ_BW                   = 16;
localparam          PZ_NUM                  = 6;
localparam          MODE_NUM                = 2;
localparam          M_LIST                  = {32'd4 , 32'd4 };
localparam          N_LIST                  = {32'd24, 32'd24};
localparam          MCW                     = 4;    // maximum column weight
localparam          XOR_ALL_EN              = 1'b1;
localparam          INFO_GAP_BW             = 3;
localparam          COLINFO_LATENCY         = 2;

localparam          Z_BW                    = PZ_NUM*PZ_BW;
localparam          ROW_MAX                 = list_max_f(M_LIST);
localparam          COL_MAX                 = list_max_f(N_LIST);
localparam          ROW_BW                  = $clog2(ROW_MAX);  // range [0:ROW_MAX-1]
localparam          COL_BW                  = $clog2(COL_MAX);  // range [0:COL_MAX-1]
localparam          SFT_BW                  = $clog2(Z_BW+1);   // range [-1:Z_BW-1]
localparam          OFST_BW                 = $clog2(PZ_NUM);   // range [0:PZ_NUM-1]
localparam          INFO_PBS_BW             = ROW_BW+SFT_BW;
localparam          MODE_BW                 = ((MODE_NUM<=1) ? 1 : $clog2(MODE_NUM));
localparam          COLINFO_AW              = ((MODE_NUM<=1) ? COL_BW : (MODE_BW+COL_BW));
localparam          COLINFO_DW              = INFO_GAP_BW+MCW*INFO_PBS_BW;

localparam          ILLR_BW                 = 4;
localparam          PLLR_BW                 = 8;
localparam          RLLR_BW                 = 6;    // RLLR_BW < PLLR_BW
//localparam          BS2RC_DLY_LIST          = {32'd32 , 32'd22 };   // MRW(@current mode) + MIN search delay
localparam          BS2RC_DLY_LIST          = {32'd32 , 32'd19 };   // MRW(@current mode) + MIN search delay
localparam          TS_END_LIST             = {32'd127, 32'd127};
localparam          ITR_END_LIST            = {32'd5  , 32'd9  };
//localparam          MRW                     = 20;   // Maximum Row weight
//localparam          MHW                     = 80;   // Maximum H Matrix weight
localparam          MRW                     = 17;   // Maximum Row weight
localparam          MHW                     = 68;   // Maximum H Matrix weight
localparam          IN_DEPTH                = 24+8;

localparam          BSFT_BW                 = $clog2(Z_BW);     // Range [ 0:Z_BW-1]
localparam          DLY_MAX                 = list_max_f(BS2RC_DLY_LIST);
localparam          TS_MAX                  = list_max_f(TS_END_LIST)+1;
localparam          ITR_MAX                 = list_max_f(ITR_END_LIST)+1;
localparam          DLY_BW                  = $clog2(DLY_MAX+1);
localparam          TS_BW                   = $clog2(TS_MAX);
localparam          ITR_BW                  = $clog2(ITR_MAX);
localparam          SQH_BW                  = $clog2(MHW);
localparam          MIN_BW                  = RLLR_BW-1;
localparam          HMT_AW                  = ((MODE_NUM<=1) ? TS_BW : (MODE_BW+TS_BW));
localparam          HMT_DW                  = COL_BW+SFT_BW+BSFT_BW+4;

`define COL_POS  0+:COL_BW
`define SFT_POS  COL_BW+:SFT_BW
`define DSFT_POS COL_BW+SFT_BW+:BSFT_BW
`define FIC_POS  HMT_DW-2
`define LIC_POS  HMT_DW-1

reg                                         rst_n;
reg                                         clk;

reg                                         msg_vld;
reg                 [PZ_BW-1:0]             msg_dat;
reg                                         msg_end;
reg                 [MODE_BW-1:0]           msg_mode;
wire                                        msg_rdy;

wire                                        colinfo_ren;
wire                [COLINFO_AW-1:0]        colinfo_raddr;
reg                 [COLINFO_DW-1:0]        colinfo_rdata;

wire                                        cw_vld;
wire                [PZ_BW-1:0]             cw_dat;
wire                                        cw_end;
wire                [MODE_BW-1:0]           cw_mode;
wire                                        cw_rdy;

reg                 [COLINFO_DW-1:0]        colinfo_ary[2**COLINFO_AW-1:0];
reg                 [COLINFO_DW-1:0]        colinfo_q;

integer H[3:0][23:0];

integer msg_idx, err_idx;

initial begin:CRG
    rst_n=1'b0;
    clk=1'b0;

    fork
        rst_n=#100.5 1'b1;
        forever clk=#CLK_PRD ~clk;
    join
end

RGRS_MNG    rgrs;
initial begin:REGRESS
    rgrs = new("tc_ldpc_dbg", 2);

    rgrs.wait_chks_done(100_000_000);
end

initial begin:GEN_MSG
    integer i, j;
    integer gap, mode;

    msg_vld  = 0;
    msg_dat  = 0;
    msg_end  = 0;
    msg_mode = 0;

    msg_idx = 0;
    @(posedge rst_n);
    @(posedge clk);

    repeat(CW_NUM) begin
        gap  = $urandom_range(0, 10);
//        mode = $urandom_range(0, 1);
//        gap  = 500;
        mode = 0;

//        gap = 500;
//        s = 1;
//        e = 4;
        //        gap; mode;
        gen_msg_t(gap, mode);
        msg_idx = msg_idx + 1;
    end
    rgrs.one_chk_done("GEN MSG num is done.");
end

eldpc_top #(
        .PZ_BW                          (PZ_BW                          ),
        .PZ_NUM                         (PZ_NUM                         ),
        .MODE_NUM                       (MODE_NUM                       ),
        .M_LIST                         (M_LIST                         ),
        .N_LIST                         (N_LIST                         ),
        .MCW                            (MCW                            ),	// maximum column weight
        .XOR_ALL_EN                     (XOR_ALL_EN                     ),
        .INFO_GAP_BW                    (INFO_GAP_BW                    ),
        .COLINFO_LATENCY                (COLINFO_LATENCY                )
) u_eldpc ( 
        .rst_n                          (rst_n                          ),
        .clk                            (clk                            ),

        .msg_vld                        (msg_vld                        ),
        .msg_dat                        (msg_dat                        ),
        .msg_end                        (msg_end                        ),
        .msg_mode                       (msg_mode                       ),
        .msg_rdy                        (msg_rdy                        ),

        .colinfo_ren                    (colinfo_ren                    ),
        .colinfo_raddr                  (colinfo_raddr                  ),
        .colinfo_rdata                  (colinfo_rdata                  ),

        .cw_vld                         (cw_vld                         ),
        .cw_dat                         (cw_dat                         ),
        .cw_end                         (cw_end                         ),
        .cw_mode                        (cw_mode                        ),
        .cw_rdy                         (cw_rdy                         )
);

reg                 [16-1:0]                cw_sqb;
wire                                        in_vld;
reg                 [PZ_BW*ILLR_BW-1:0]     in_llr;
wire                                        in_eob;     // end of code-word block
wire                [MODE_BW-1:0]           in_mode;
wire                                        in_rdy;

wire                                        hmt_ren;
wire                [HMT_AW-1:0]            hmt_raddr;
reg                 [HMT_DW-1:0]            hmt_rdata;
reg                 [HMT_DW-1:0]            hmt_q;
reg                 [HMT_DW-1:0]            hmt_ary[TS_MAX-1:0];

wire                                        out_vld;
wire                [PZ_BW-1:0]             out_dat;
wire                                        out_eob;     // end of code-word block
wire                [MODE_BW-1:0]           out_mode;
reg                                         out_rdy;

always@(posedge clk or negedge rst_n) begin
    if (rst_n==1'b0) begin
        cw_sqb <=`U_DLY 16'd0;
    end else begin
        if ((cw_vld&cw_rdy)==1'b1) begin
            if (cw_end==1'b1)
                cw_sqb <=`U_DLY 16'd0;
            else
                cw_sqb <=`U_DLY cw_sqb+1'd1;
        end else
            ;
    end
end

assign in_vld = cw_vld;
assign in_eob = cw_end;
assign in_mode = cw_mode;
assign cw_rdy  = in_rdy;

always@(*) begin:LLR
    integer i;

    for (i=0; i<PZ_BW; i=i+1) begin
         in_llr[i*ILLR_BW+:ILLR_BW] = ((cw_sqb<=$urandom_range(0,7)) && (i<=3)) ? ((cw_dat[i]==1'b1) ? 4'b0010 : 4'b1101) :
                                      (cw_dat[i]==1'b0) ? 4'b0011 : 4'b1100;    // +3 : -4
//         in_llr[i*ILLR_BW+:ILLR_BW] = (cw_dat[i]==1'b0) ? 4'b0011 : 4'b1100;    // +3 : -4
    end
end

dldpc_top #(
        .PZ_BW                          (PZ_BW                          ),
        .PZ_NUM                         (PZ_NUM                         ),
        .ILLR_BW                        (ILLR_BW                        ),
        .PLLR_BW                        (PLLR_BW                        ),
        .RLLR_BW                        (RLLR_BW                        ),	// RLLR_BW < PLLR_BW
        .MODE_NUM                       (MODE_NUM                       ),
        .N_LIST                         (N_LIST                         ),
        .BS2RC_DLY_LIST                 (BS2RC_DLY_LIST                 ),
        .TS_END_LIST                    (TS_END_LIST                    ),
        .ITR_END_LIST                   (ITR_END_LIST                   ),
        .ROW_MAX                        (ROW_MAX                        ),
        .MRW                            (MRW                            ),	// Maximum Row weight
        .MHW                            (MHW                            ),	// Maximum H Matrix weight
        .IN_DEPTH                       (IN_DEPTH                       ),
        .DPB_ADRCMPS_EN                 (1'b1                           )
) u_dldpc_top ( 
        .rst_in_n                       (rst_n                          ),
        .clk_in                         (clk                            ),	// clock for input LLR

        .in_vld                         (in_vld                         ),
        .in_llr                         (in_llr                         ),
        .in_eob                         (in_eob                         ),	// end of code-word block
        .in_mode                        (in_mode                        ),
        .in_rdy                         (in_rdy                         ),

        .rst_itr_n                      (rst_n                          ),
        .clk_itr                        (clk                            ),	// clock for decoding iteration

        .hmt_ren                        (hmt_ren                        ),
        .hmt_raddr                      (hmt_raddr                      ),
        .hmt_rdata                      (hmt_rdata                      ),

        .out_vld                        (out_vld                        ),
        .out_dat                        (out_dat                        ),
        .out_eob                        (out_eob                        ),	// end of code-word block
        .out_mode                       (out_mode                       ),
        .out_rdy                        (out_rdy                        ),

        .cfg_llr_delta                  (5'd1                           )
);

always@(posedge clk) begin
    if (colinfo_ren==1'b1) begin
        colinfo_q <=`U_DLY colinfo_ary[colinfo_raddr];
    end

    colinfo_rdata <=`U_DLY colinfo_q;
end

always@(posedge clk) begin
    if (hmt_ren==1'b1) begin
        hmt_q <=`U_DLY hmt_ary[hmt_raddr];
    end

    hmt_rdata <=`U_DLY hmt_q;
end

always@(posedge clk or negedge rst_n) begin
    if (rst_n==1'b0) begin
        out_rdy <=`U_DLY 1'b1;
    end else begin
        out_rdy <=`U_DLY ($urandom_range(1, 1000)<800) ? 1'b1 : 1'b0;
    end
end

initial begin:H_INI
    integer i, j;
    integer ts_end;
    logic [23:0] flag_ary;
    logic [BSFT_BW-1:0] sft_ary[23:0];

//         // 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0
//    H[0] = {-1, -1,  0, 80, -1, 19, 55, 92, 94, -1, 36, 13, 43, 30, 22, 95, 89,  7, 31, 77, 67, 69, 71,  1};
//    H[1] = {-1,  0,  0, -1, 20, 57, 18, 53, -1, 40, 14, 45, 12, 41, 28, 93,  8, 33,  6, 29, 75, -1,  2, 21};
//    H[2] = { 0,  0, -1,  0, 59, -1, -1, 17, 51, 15, 47, 34, 24, 11, -1,  9, 35, 85, 81,  5, 27,  3, 23, 61};
//    H[3] = { 0, -1, -1, 80, 65, 90, 88, -1, 16, 49, -1, 38, 32, 26, 10, 37, 91, 87, 83, 79,  4, 25, 63, 73};

         // 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0
    H[0] = {-1, -1,  0, 80, -1, 19, 55, 92, 94, -1, 36, -1, 43, 30, 22, 95, -1,  7, 31, 77, -1, 69, 71,  1};
    H[1] = {-1,  0,  0, -1, 20, 57, 18, 53, -1, 40, -1, 45, 12, 41, 28, -1,  8, 33,  6, -1, 75, -1,  2, 21};
    H[2] = { 0,  0, -1,  0, 59, -1, -1, 17, 51, 15, 47, 34, 24, -1, -1,  9, 35, 85, -1,  5, 27,  3, 23, -1};
    H[3] = { 0, -1, -1, 80, 65, 90, 88, -1, 16, 49, -1, 38, -1, 26, 10, 37, 91, -1, 83, 79,  4, 25, -1, 73};

    for (j=0; j<24; j=j+1) begin
        for (i=0; i<4; i=i+1) begin
            colinfo_ary[j][i*INFO_PBS_BW+:SFT_BW] = H[(i==0) ? 3 : i-1][j];
            colinfo_ary[j][i*INFO_PBS_BW+SFT_BW+:ROW_BW] = i;
        end
        colinfo_ary[j][4*INFO_PBS_BW+:INFO_GAP_BW] = 0;
    end
    colinfo_ary[19][4*INFO_PBS_BW+:INFO_GAP_BW] = 5;

//    for (i=0; i<4; i=i+1) begin
//        for (j=0; j<24; j=j+1) begin
//            if (H[i][j]>=0) begin
//                $display("hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd%0d, 5'd%0d};", H[i][j], j);
//            end
//        end
//    end
                     // lic,  fic,  eoh,  eor, dsft,  sft  ,  col
//    i=0;   hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd1  , 5'd0 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd71 , 5'd1 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd69 , 5'd2 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd67 , 5'd3 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd77 , 5'd4 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd31 , 5'd5 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd7  , 5'd6 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd89 , 5'd7 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd95 , 5'd8 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd22 , 5'd9 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd30 , 5'd10};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd43 , 5'd11};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd13 , 5'd12};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd36 , 5'd13};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd94 , 5'd15};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd92 , 5'd16};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd55 , 5'd17};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd19 , 5'd18};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd80 , 5'd20};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b1, 7'd0, 7'd0  , 5'd21};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd21, 5'd0 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd2 , 5'd1 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd75, 5'd3 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd29, 5'd4 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd6 , 5'd5 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd33, 5'd6 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd8 , 5'd7 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd93, 5'd8 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd28, 5'd9 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd41, 5'd10};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd12, 5'd11};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd45, 5'd12};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd14, 5'd13};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd40, 5'd14};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd53, 5'd16};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd18, 5'd17};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd57, 5'd18};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd20, 5'd19};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd0 , 5'd21};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b1, 7'd0, 7'd0 , 5'd22};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd61, 5'd0 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd23, 5'd1 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd3 , 5'd2 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd27, 5'd3 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd5 , 5'd4 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd81, 5'd5 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd85, 5'd6 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd35, 5'd7 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd9 , 5'd8 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd11, 5'd10};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd24, 5'd11};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd34, 5'd12};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd47, 5'd13};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd15, 5'd14};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd51, 5'd15};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd17, 5'd16};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd59, 5'd19};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd0 , 5'd20};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd0 , 5'd22};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b1, 7'd0, 7'd0 , 5'd23};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd73, 5'd0 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd63, 5'd1 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd25, 5'd2 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd4 , 5'd3 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd79, 5'd4 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd83, 5'd5 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd87, 5'd6 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd91, 5'd7 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd37, 5'd8 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd10, 5'd9 };
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd26, 5'd10};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd32, 5'd11};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd38, 5'd12};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd49, 5'd14};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd16, 5'd15};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd88, 5'd17};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd90, 5'd18};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd65, 5'd19};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd80, 5'd20}; 
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b1, 1'b1, 7'd0, 7'd0 , 5'd23};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
//    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};

                     // lic,  fic,  eoh,  eor, dsft,  sft  ,  col
    i=0;   hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd1, 5'd0  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd71, 5'd1 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd69, 5'd2 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd77, 5'd4 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd31, 5'd5 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd7, 5'd6  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd95, 5'd8 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd22, 5'd9 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd30, 5'd10};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd43, 5'd11};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd36, 5'd13};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd94, 5'd15};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd92, 5'd16};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd55, 5'd17};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd19, 5'd18};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd80, 5'd20};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b1, 7'd0, 7'd0, 5'd21 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};

    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd21, 5'd0 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd2, 5'd1  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd75, 5'd3 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd6, 5'd5  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd33, 5'd6 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd8, 5'd7  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd28, 5'd9 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd41, 5'd10};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd12, 5'd11};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd45, 5'd12};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd40, 5'd14};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd53, 5'd16};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd18, 5'd17};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd57, 5'd18};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd20, 5'd19};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd0, 5'd21 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b1, 7'd0, 7'd0, 5'd22 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};

    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd23, 5'd1 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd3, 5'd2  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd27, 5'd3 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd5, 5'd4  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd85, 5'd6 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd35, 5'd7 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd9, 5'd8  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd24, 5'd11};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd34, 5'd12};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd47, 5'd13};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd15, 5'd14};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd51, 5'd15};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd17, 5'd16};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd59, 5'd19};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd0, 5'd20 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd0, 5'd22 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b1, 7'd0, 7'd0, 5'd23 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};

    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd73, 5'd0 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd25, 5'd2 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd4, 5'd3  };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd79, 5'd4 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd83, 5'd5 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd91, 5'd7 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd37, 5'd8 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd10, 5'd9 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd26, 5'd10};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd38, 5'd12};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd49, 5'd14};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd16, 5'd15};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd88, 5'd17};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd90, 5'd18};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd65, 5'd19};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd80, 5'd20};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b1, 1'b1, 7'd0, 7'd0, 5'd23 };
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};
    i=i+1; hmt_ary[i]={1'b0, 1'b0, 1'b0, 1'b0, 7'd0, 7'd127, 5'd31};

    ts_end = i;

    // fic
    flag_ary[23:0]={24{1'b1}};
    for (i=0; i<=ts_end; i=i+1) begin
        if ((&hmt_ary[i][`SFT_POS])==1'b0) begin
            hmt_ary[i][`FIC_POS]=flag_ary[hmt_ary[i][`COL_POS]];
            flag_ary[hmt_ary[i][`COL_POS]]=1'b0;

            sft_ary[hmt_ary[i][`COL_POS]]=hmt_ary[i][`SFT_POS];
        end
    end

    // lic
    flag_ary[23:0]={24{1'b1}};
    for (i=ts_end; i>=0; i=i-1) begin
        if ((&hmt_ary[i][`SFT_POS])==1'b0) begin
            hmt_ary[i][`LIC_POS]=flag_ary[hmt_ary[i][`COL_POS]];
            flag_ary[hmt_ary[i][`COL_POS]]=1'b0;
        end
    end

    // dsft
    for (i=0; i<=ts_end; i=i+1) begin
        if ((&hmt_ary[i][`SFT_POS])==1'b0) begin
            hmt_ary[i][`DSFT_POS]=(hmt_ary[i][`SFT_POS]>=sft_ary[hmt_ary[i][`COL_POS]]) ? (hmt_ary[i][`SFT_POS]-sft_ary[hmt_ary[i][`COL_POS]]) : 
                                                                                     (Z_BW+hmt_ary[i][`SFT_POS]-sft_ary[hmt_ary[i][`COL_POS]]) ;

            sft_ary[hmt_ary[i][`COL_POS]]=hmt_ary[i][`SFT_POS];
        end
    end
end

//initial begin:CHK_CW
//    reg [Z_BW-1:0] tmp_dat;
//    reg [Z_BW-1:0] rx_cw[23:0];
//    reg go_on;
//    reg err_flag;
//    integer i, j;
//
//    err_flag = 0;
//
//    @(posedge rst_n);
//
//    forever begin
//        i = 0;
//        j = 0;
//        go_on = 1'b1;
//        while(go_on==1'b1) begin
//            @(posedge clk);
//            while((cw_vld&cw_rdy)==1'b0) begin
//                @(posedge clk);
//            end
//
//            tmp_dat[j*PZ_BW+:PZ_BW] = cw_dat;
//
//            if (cw_end==1'b1) begin
//                go_on = 1'b0;
//            end
//
//            if (j==PZ_NUM-1) begin
//                rx_cw[i] = tmp_dat;
//                $display("%2d:%24h", i, tmp_dat);
//                i = i+1;
//                j = 0;
//            end else begin
//                j = j+1;
//            end
//        end
//        $display("");
//
//        for (i=0; i<4; i=i+1) begin
//            tmp_dat = 0;
//            for (j=0; j<24; j=j+1) begin
//                tmp_dat = tmp_dat ^ bsr_f(rx_cw[j], H[i][j]);
////                $display("%d:%24h", H[i][j], tmp_dat);
//            end
//
//            $display("%1d:%24h", i, tmp_dat);
//            if ((|tmp_dat)==1'b1) begin
//                err_flag = 1'b1;
//                $error("%1d:%24h", i, tmp_dat);
//                $stop;
//            end
//        end
//    end
//end

initial begin:CHK_OUT
    reg [Z_BW-1:0] tmp_dat;
    reg [Z_BW-1:0] rx_cw[23:0];
    reg go_on;
    reg err_flag;
    integer i, j;

    err_idx = 0;
    err_flag = 0;

    @(posedge rst_n);

    while(err_idx<CW_NUM) begin
        i = 0;
        j = 0;
        go_on = 1'b1;
        while(go_on==1'b1) begin
            @(posedge clk);
            while((out_vld&out_rdy)==1'b0) begin
                @(posedge clk);
            end

            tmp_dat[j*PZ_BW+:PZ_BW] = out_dat;

            if (out_eob==1'b1) begin
                go_on = 1'b0;
            end

            if (j==PZ_NUM-1) begin
                rx_cw[i] = tmp_dat;
//                $display("%2d:%24h", i, tmp_dat);
                i = i+1;
                j = 0;
            end else begin
                j = j+1;
            end
        end
//        $display("");

        for (i=0; i<4; i=i+1) begin
            tmp_dat = 0;
            for (j=0; j<24; j=j+1) begin
                tmp_dat = tmp_dat ^ bsr_f(rx_cw[j], H[i][j]);
//                $display("%d:%24h", H[i][j], tmp_dat);
            end

//            $display("%1d:%24h", i, tmp_dat);
            if ((|tmp_dat)==1'b1) begin
                err_flag = 1'b1;
                $error("%1d:%24h", i, tmp_dat);
                $stop;
            end
        end

        err_idx = err_idx + 1;
    end
    rgrs.one_chk_done("CHK CW num is done.");
end

task gen_msg_t; 
    input integer gap;
    input integer mode;

    integer m, n, K, i;
    begin
        m = M_LIST[mode*32+:32];
        n = N_LIST[mode*32+:32];
        K = (n-m)*PZ_NUM;

        repeat(gap) begin
            @(posedge clk);
        end
    
        msg_mode <=`U_DLY mode;
        msg_vld  <=`U_DLY 1'b1;
        for (i=0; i<K; i=i+1) begin
            msg_dat <=`U_DLY $urandom();
//            msg_dat <=`U_DLY msg_dat + 1'd1;
//            if (i==0)
//                msg_dat <=`U_DLY 16'h8000;
//            else
//                msg_dat <=`U_DLY 16'h0000;
             
            if (i==K-1) begin
                msg_end <=`U_DLY 1'b1;
            end

            @(posedge clk);
            while(msg_rdy==1'b0) begin
                @(posedge clk);
            end
        end
        msg_vld <=`U_DLY 1'b0;
        msg_end <=`U_DLY 1'b0;
    end
endtask

function [Z_BW-1:0] bsr_f;
    input [Z_BW-1:0] dat;
    input integer sft;

    begin
        if (sft<0)
            bsr_f = {Z_BW{1'b0}};
        else
            bsr_f = (dat>>sft) | (dat<<(Z_BW-sft));
    end
endfunction

function integer list_max_f;
    input [MODE_NUM*32-1:0] list;

    integer i;
    begin
        list_max_f = list[0*32+:32];

        for (i=1; i<MODE_NUM; i=i+1) begin
            if (list_max_f<list[i*32+:32]) begin
                 list_max_f = list[i*32+:32];
            end
        end
    end
endfunction

function [MODE_NUM*32-1:0] list_sub_f;
    input [MODE_NUM*32-1:0] a_list;
    input [MODE_NUM*32-1:0] b_list;

    integer i;
    begin
        for (i=0; i<MODE_NUM; i=i+1) begin
             list_sub_f[i*32+:32] = a_list[i*32+:32] - b_list[i*32+:32];
        end
    end
endfunction

function [MODE_NUM*32-1:0] list_dec_f;
    input [MODE_NUM*32-1:0] list;
    input [31:0]            diff;

    integer i;
    begin
        for (i=0; i<MODE_NUM; i=i+1) begin
             list_dec_f[i*32+:32] = list[i*32+:32] - diff;
        end
    end
endfunction

endmodule

